package net.qhzw.vip.qiyu.controller;

import com.alibaba.fastjson.JSON;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.vip.qiyu.config.ApiConfig;
import net.qhzw.vip.qiyu.config.WxProperties;
import net.qhzw.vip.qiyu.dto.PayInfoDto;
import net.qhzw.vip.qiyu.handler.ApiException;
import net.qhzw.vip.qiyu.param.PayParam;
import net.qhzw.vip.qiyu.result.JsonResult;
import net.qhzw.vip.qiyu.service.PayService;
import net.qhzw.vip.qiyu.util.Arith;
import net.qhzw.vip.qiyu.util.IPHelper;
import net.qhzw.vip.qiyu.util.Json;
import net.qhzw.vip.qiyu.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/p/order")
@Api(tags = "订单支付接口")
@Slf4j
public class PayController {

    @Autowired
    private WxProperties properties;

    @Autowired
    private PayService payService;

    @Autowired
    private ApiConfig apiConfig;

//    @Autowired
//    private WxPayService wxMiniPayService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @PostMapping("refund")
    public JsonResult refund(@RequestBody PayParam payParam) {
        Long userId = SecurityUtils.getUserId();
        WxPayRefundResult refund = payService.refund(userId, payParam);
        return JsonResult.ok(refund);
    }


    @PostMapping("/pay")
    @ApiOperation(value = "根据订单号进行支付", notes = "根据订单号进行支付")
    @SneakyThrows
    public JsonResult<WxPayMpOrderResult> pay(@RequestBody PayParam payParam) {
        log.info("【根据订单号进行支付】：", JSON.toJSONString(payParam));
        Long userId = SecurityUtils.getUserId();
        String openId = getUserOpenId(userId);
        PayInfoDto payInfo = payService.pay(userId, payParam);
        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setBody(payInfo.getBody());
        orderRequest.setOutTradeNo(payInfo.getPayNo());
        orderRequest.setTotalFee((int) Arith.mul(payInfo.getPayAmount(), 100));
        orderRequest.setSpbillCreateIp(IPHelper.getIpAddr());
        orderRequest.setNotifyUrl(apiConfig.getDomainName() + "/mall/notice/pay/order");
        orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
        orderRequest.setOpenid(openId);

        // =========== 支付 ================
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(properties.getAppId());
        payConfig.setMchId(properties.getMchId());
        payConfig.setMchKey(properties.getMchKey());
        payConfig.setKeyPath(properties.getKeyPath());
        payConfig.setSignType(WxPayConstants.SignType.MD5);
        payConfig.setTradeType("JSAPI");
        payConfig.setSignType("MD5");
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        WxPayMpOrderResult wxPayMpOrderResult = wxPayService.createOrder(orderRequest);
        log.info("根据订单号进行支付: {}", Json.toJsonString(wxPayMpOrderResult));
        return JsonResult.ok(wxPayMpOrderResult);
    }

    /**
     * 普通支付接口
     */
    @PostMapping("/normalPay")
    @ApiOperation(value = "根据订单号进行支付", notes = "根据订单号进行支付")
    @SneakyThrows
    public ResponseEntity<Boolean> normalPay(@RequestBody PayParam payParam) {
        Long userId = SecurityUtils.getUserId();
        PayInfoDto pay = payService.pay(userId, payParam);
        // 根据内部订单号更新order settlement
        payService.paySuccess(pay.getPayNo(), "");
        return ResponseEntity.ok(true);
    }

    private String getUserOpenId(Long userId) {
        JsonResult<String> jsonResult = restTemplate.getForObject("http://lease-server/getUserOpenidById/" + userId, JsonResult.class);
        //JsonResult<String> jsonResult = restTemplate.getForObject("http://" + instance.getHost() + ":" + instance.getPort() + "/getUserOpenidById/" + userId, JsonResult.class);
        if (jsonResult.getCode() == 200) {
            String weixinOpenid = jsonResult.getData();
            return weixinOpenid;
        }
        throw new ApiException("用户信息有误, 请联系管理员！");
    }

}
